package at.ptasat.solver.process;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.Thread.UncaughtExceptionHandler;

public class PollingRedirection {

	private final InputStream in;
	private final OutputStream out;
	private final Thread worker;

	public PollingRedirection(InputStream in, OutputStream out) {
		this(in, out, PollingRedirection.class.getName());
	}

	public PollingRedirection(InputStream in, OutputStream out, String name) {
		if (in == null || out == null) {
			throw new NullPointerException();
		}
		this.in = in;
		this.out = out;
		worker = new Thread(new MyRunnable());
		worker.setName(name);
		worker.setDaemon(true);
		worker.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
			@Override
			public void uncaughtException(Thread _, Throwable error) {
				// nothing to do
			}
		});
		worker.start();
	}

	private final class MyRunnable implements Runnable {
		@Override
		public void run() {
			assert Thread.currentThread().equals(worker);
			try {
				final byte[] buffer = new byte[1024];
				int nRead = 0;
				while (!worker.isInterrupted()) {
					nRead = in.read(buffer);
					if (nRead < 0) {
						worker.interrupt();
					} else {
						out.write(buffer, 0, nRead);
					}
				}
			} catch (IOException e) {
				// nothing to do
			}
		}
	}

	public void close() throws IOException, InterruptedException {
		in.close();
		worker.interrupt();
		worker.join();
		out.close();
	}
}
